/**
 * @fileOverview Dialog for thesaurus.
 */
VED.dialog.add( 'thesaurus', function( editor ) {

   var plugin = VED.plugins.link,
       lang   = editor.lang.thesaurus;

   // Класс для создания выпадающего списка с поиском (Наследуем от класса VED.event)
   var cBoundList = VED.event.extend({
      initialize: function( editor, input, config ) {
         this.config = VED.tools.extend( {
            lang: 'ru',
            onAccept: function() {}
         }, config, true );

         var processed, stopPropagation;
         this._ = {
            editor: editor,
            dialog: input.getDialog(),
            input: input,
            active: false,
            selectedIndex: -1,
            searchText: '',
            items: [],
            itemsCount: 0
         };

         this._.itemClickFn = VED.tools.addFunction( function( index ) {
            this.selectItem( index );
            this.acceptItem();
            this.hide();
            this.loadItems();

         }, this );

         this._.itemOverFn = VED.tools.addFunction( function( index ) {
            this.selectItem( index, true );
         }, this );

         this._.listOutFn = VED.tools.addFunction( function(evt,el) {
            evt = new VED.dom.event(evt);
            el  = new VED.dom.element(el);
            var rTarget = VED.dom.element.get( evt.$.toElement || evt.$.fromElement || evt.$.relatedTarget );
            if ( !( rTarget && ( el.equals(rTarget) || el.contains(rTarget) ) ) ) {
               var selectedEl = this._.div.getChild([ 0, 0 ]).getChildren().getItem( this._.selectedIndex );
               selectedEl && selectedEl.removeClass( 'ved_boundlist_list_over' );
               this._.selectedIndex = -1;
            }
         }, this);

         var templateSource = '<div class="ved_reset_all ved_boundlist {editorId}" dir="{langDir}" lang="{langCode}" role="listbox">' +
               '<div class="ved_boundlist_list ved_{langDir}" onmouseout="VED.tools.callFunction({listOut},event,this);">' +
                  '<ul></ul>' +
               '</div>' +
            '</div>'

         var startStyles = {
            position: VED.env.ie6Compat ? 'absolute' : 'fixed',
            top: 0
         };

         startStyles[ editor.lang.dir == 'rtl' ? 'right' : 'left' ] = 0;

         this._.div = VED.dom.element.createFromHtml( VED.addTemplate( 'boundlist', templateSource ).output({
            id: VED.tools.getNextNumber(),
            editorId: editor.id,
            langDir: editor.lang.dir,
            langCode: editor.langCode,
            listOut: this._.listOutFn
         }));

         this._.div.setStyles( startStyles );

         var me = this;

         function keydownHandler( evt ) {

            var keystroke = evt.data.getKeystroke(),
                text = input.getValue();

            processed = stopPropagation = 0;


            if( keystroke == 38 && me._.active ) { // Стрелка вверх
               me.selectItem('prev');
            } else if( keystroke == 40 && me._.itemsCount > 0 ) { // Стрелка вниз
               if( !me._.active ) {
                  me.show();
                  processed = 1;
               } else {
                  me.selectItem('next');
               }

            } else if( me._.active && keystroke == 27 ) { // ESC
               me.hide();
               stopPropagation = 1; // Прерываем событие, чтобы не закрылся диалог
            } else if( me._.active && keystroke == 13 ) { // Enter
               me.acceptItem();
               me.hide();
               me.loadItems();

               // Прерываем событие, чтобы не закрылся диалог
               evt.stop();
               stopPropagation = 1;
            }

            keypressHandler( evt );
         }

         var positition = 0;

         function keyupHandler( evt ) {
            var keystroke = evt.data.getKeystroke();

            // Игнорируем некоторые клавиши
            if( keystroke in {
               // 9:1,     // Tab
               // 13:1,
               35:1,    // End
               36:1,    // Home
               // 37:1,    // Left
               38:1,    // Top
               // 39:1,    // Right
               40:1,    // Down
               45:1     // Insert
            } ) return;


            var inputText = input.getValue();  // Полный текст поискового поля

            if ( me._.timer )
               clearTimeout( me._.timer );

            me._.timer = VED.tools.setTimeout( function() {
               delete me._.timer;
               if( me._.searchText != inputText ) {
                  me._.searchText = inputText;
                  if( me._.searchText.length > 0 ) {
                     me.loadItems( function() {
                        me._.selectedIndex = -1;
                        if( me._.itemsCount > 0 && !me._.active ) {
                           me.show();
                           // me.selectItem(0);
                        }
                     });
                  } else {
                     me.clearItems();
                     me._.active && me.hide();
                  }
               }
            }, 300, this );

            processed = stopPropagation = 0;

            if( keystroke == 13 ) {
               evt.stop();
               stopPropagation = 1;
            }

            keypressHandler( evt );

         }

         function keypressHandler( evt ) {
            if ( processed )
               evt.data.preventDefault( 1 );
            else if ( stopPropagation )
               evt.data.stopPropagation();
         }

         // Начинаем слушать клавиши при открытии диалога
         this._.dialog.on( 'show', function() {
            input.getInputElement().on('keydown', keydownHandler, this );
            input.getInputElement().on('keyup', keyupHandler, this );
            if ( VED.env.opera || VED.env.gecko )
               input.getInputElement().on( 'keypress', keypressHandler, this );

         });

         // Убиваем события клавиш при закрытии диалога
         this._.dialog.on( 'hide', function( evt ) {
            input.getInputElement().removeListener( 'keydown', keydownHandler );
            if ( VED.env.opera || VED.env.gecko )
               input.getInputElement().removeListener( 'keypress', keypressHandler );

         });

         // Закрываем список, если кликнули мимо
         this._.overClickHandler = function( evt ) {
            var target = evt.data.getTarget();
            if( !me._.div.contains(target) && !target.isIdentical( me._.input.getInputElement() ) ) {
               me.hide();
            }
         }

      },

      show: function() {
         var div = this._.div,
             input = this._.input.getElement();

         if ( !( div.getParent() && div.getParent().equals( VED.document.getBody() ) ) ) {
            div.appendTo( VED.document.getBody() );
         } else {
            div.setStyle( 'display', 'block' );
         }

         // Set z-index.
         if ( VED.dialog._.currentZIndex === null )
            VED.dialog._.currentZIndex = this._.editor.config.baseFloatZIndex;
         div.setStyle( 'z-index', VED.dialog._.currentZIndex += 10 );

         var scrollPosition = VED.document.getWindow().getScrollPosition();
         div.setStyles({
            'top':  ( input.getDocumentPosition().y + input.getSize('height') - scrollPosition.y ) + 'px',
            'left': ( input.getDocumentPosition().x - scrollPosition.x ) + 'px'
         });

         div.getFirst().setStyles({
            'width': ( input.getSize('width') - 2 ) + 'px'//,
            // 'height': "150px"
         });

         this._.active = true;

         if ( VED.dialog._.currentTop === null ) {
            this._.parentDialog = null;
         } else {
            this._.parentDialog = VED.dialog._.currentTop;
            // var parentElement = this._.parentDialog.getElement().getFirst();
            // parentElement.$.style.zIndex -= Math.floor( this._.editor.config.baseFloatZIndex / 2 );
         }

         // Закрыть выпадающий список, если закрыто окно диалога
         this._.editor.on( 'dialogHide', function(ev){
            this.hide();
         }, this);

         VED.document.on('click', this._.overClickHandler);

      },

      hide: function() {
         if ( !this._.div.isVisible() )
            return;

         this.fire( 'hide', {} );

         var div = this._.div;
         div.setStyle( 'display', 'none' );

         this._.active = false;

         // Deduct or clear the z-index.
         VED.dialog._.currentZIndex -= 10;

         VED.document.removeListener('click', this._.overClickHandler);

         delete this._.parentDialog;

      },

      loadItems: function( callback ) {
         var me = this;
         Page.sendAction('get_terms_list', {word: this._.searchText, lang: this.config.lang}, function(res){
            if( res && res.data ) {
               me._.items = res.data;
               me._.itemsCount = res.data.length;
               me.clearItems();
               var ul = me._.div.getChild([ 0, 0 ]),
                   liTemplate = VED.addTemplate( 'bounditem', '<li value="{value}" onclick="VED.tools.callFunction({clickFn},{num});" onmouseover="VED.tools.callFunction({overFn},{num});">{html}</li>' );
               for( var i = 0; i < res.data.length; i ++ ) {
                  var item = res.data[i];
                  var li = VED.dom.element.createFromHtml( liTemplate.output({
                     value: item.external_id,
                     overFn: me._.itemOverFn,
                     clickFn: me._.itemClickFn,
                     num: i,
                     html: item.name
                  }));
                  // li.setAttribute( 'value', item.external_id ).setHtml( item.name );
                  // li.setAttribute( 'onmouseover', 'VED.tools.callFunction(' + me._.itemOverFn + ',' + i + ');' );
                  // li.setAttribute( 'onclick', 'VED.tools.callFunction(' + me._.itemClickFn + ',' + i + ');' );

                  // me.attachItemHandlers( li );
                  ul.append(li);
               }
            }
            if( typeof callback == 'function' ) callback()
         });

      },

      clearItems: function() {
         this._.div.getChild([ 0, 0 ]).setHtml('');
      },

      selectItem: function( index, fix_text ) {
         if( !this._.active ) return false;

         if( index == 'prev' ) {
            index = this._.selectedIndex - 1;
            if( index < -1 ) {
               index = this._.itemsCount - 1;
            }

         } else if( index == 'next' ) {
            index = this._.selectedIndex + 1;
            if( index >= this._.itemsCount ) {
               index = -1;
            }

         } else if( !isNaN( parseInt( index ) ) ) {
            // if( this._.selectedIndex == index ) return false;
            if( index >= this._.itemsCount || index < -1 ) return false;

         }

         var list = this._.div.getChild([ 0, 0 ]).getChildren();

         if( list.getItem( this._.selectedIndex ) ) {
            list.getItem( this._.selectedIndex ).removeClass( 'ved_boundlist_list_over' );
         }

         if( list.getItem( index ) ) {
            var li = list.getItem( index );
            li.addClass( 'ved_boundlist_list_over' );
            li.scrollIntoView();

            var item = this._.items[index];
            item && !fix_text && this._.input.setValue( item.name );
            this._.selectedIndex = index;
         } else if( index == -1 ) {
            this._.input.setValue( this._.searchText );
            this._.selectedIndex = index;
         }

      },

      acceptItem: function() {
         var item = this._.items[this._.selectedIndex];
         if( item ) {
            this._.searchText = item.name;
            if( typeof this.config.onAccept == 'function' ) {
               this.config.onAccept.call( this._.input, item.external_id, item.name );
            }
         }

      }

   });


   var parseLink = function( editor, element ) {
      var sourceRuRegex = new RegExp( "^" + editor.config.thesaurusSourcePatternRu.replace( /\{term_id\}/, '(\\d+)' ).replace(/\./g, '\\.') + "$" ),
          sourceEnRegex = new RegExp( "^" + editor.config.thesaurusSourcePatternEn.replace( /\{term_id\}/, '(\\d+)' ).replace(/\./g, '\\.') + "$" );



      var href = ( element && ( element.data( 'ved-saved-href' ) || element.getAttribute( 'href' ) ) ) || '',
         xtagname = ( element  && ( element.data( 'ved-saved-xtagname' ) || element.getAttribute( 'xtagname' ) ) ) || '',
         javascriptMatch, emailMatch, anchorMatch, urlMatch,
         retval = {};

      if( href ) {
         if ( urlMatch = href.match( sourceRuRegex ) ) {
            retval.lang = 'ru';
            retval.term_id = urlMatch[ 1 ];
         } else if ( urlMatch = href.match( sourceEnRegex ) ) {
            retval.lang = 'en';
            retval.term_id = urlMatch[ 1 ];
         }
      }

      // Record down the selected element in the dialog.
      this._.selectedElement = element;
      return retval;
   };


   var boundList, boundListEn;

   var dialogDefiniton = {
      title: lang.title,
      minWidth: 360,
      minHeight: 220,
      contents: [
         {
            id: 'russian',
            label: lang.rus_terms,
            title: lang.rus_terms,
            elements: [
               {
                  type: 'hbox',
                  widths: [ null, null ],
                  styles: [ 'vertical-align:top' ],
                  children: [
                     {
                        type: 'vbox',
                        padding: 0,
                        children: [
                           {
                              id: 'rusTermsList',
                              type: 'text',
                              label: lang.term,
                              'default': '',
                              // required: true,
                              onLoad: function(){
                                 if( !boundList ) boundList = new cBoundList( editor, this, {
                                    lang: 'ru',
                                    onAccept: function( id, name ) {
                                       this.getDialog().setValueOf('russian', 'rusTermId', id );
                                       var el_html = this.getDialog().getContentElement('russian','descriptionText').getInputElement();
                                       el_html.setHtml('');
                                       Page.sendAction('get_term',{id:id, lang:'ru'}, function( result ){
                                          if( result && result.desc ) {
                                             el_html.setHtml('<div class="ved_thesaurus_desc">' + result.desc + '</div>');
                                          }
                                       });
                                    }
                                 });
                              },
                              setup: function( data ) {
                                 if( data.term_id ) {
                                    var me = this;
                                    Page.sendAction('get_term',{id:data.term_id, lang:'ru'}, function( result ){
                                       if( result && result.name ) {
                                          me.setValue( result.name );
                                          me.getDialog().getContentElement('russian','descriptionText').getInputElement().setHtml('<div class="ved_thesaurus_desc">' + result.desc + '</div>');
                                       }
                                    });

                                 }
                              },
                              commit: function( data ) {
                                 if( this.getDialog()._.currentTabId == 'russian' )
                                    data.name = this.getValue();
                              }
                           },
                           {
                              id: 'rusTermId',
                              type: 'text',
                              label: 'TermId',
                              hidden: true,
                              'default': '',
                              setup: function( data ) {
                                 if( data.term_id )
                                    this.setValue( data.term_id );
                              },
                              commit: function( data ) {
                                 if( this.getDialog()._.currentTabId == 'russian' )
                                    data.term_id = this.getValue();
                              }
                           },
                           {
                              id: 'descriptionText',
                              type: 'html',
                              // style: 'display:block; padding-top: 5px; white-space: normal;',
                              html: '',
                              reset: function() {
                                 this.getInputElement().setHtml('');
                              }
                           }
                        ]
                     }
                  ]
               }
            ]
         },
         {
            id: 'english',
            label: lang.eng_terms,
            title: lang.eng_terms,
            elements: [
               {
                  type: 'hbox',
                  widths: [ null, null ],
                  styles: [ 'vertical-align:top' ],
                  children: [
                     {
                        type: 'vbox',
                        padding: 0,
                        children: [
                           {
                              id: 'engTermsList',
                              type: 'text',
                              label: lang.term,
                              'default': '',
                              // required: true,
                              onLoad: function(){
                                 if( !boundListEn ) boundListEn = new cBoundList( editor, this, {
                                    lang: 'en',
                                    onAccept: function( id, name ) {
                                       this.getDialog().setValueOf('english', 'engTermId', id );
                                       var el_html = this.getDialog().getContentElement('english','descriptionText').getInputElement();
                                       el_html.setHtml('');
                                       Page.sendAction('get_term',{id:id, lang:'en'}, function( result ){
                                          if( result && result.desc ) {
                                             el_html.setHtml('<div class="ved_thesaurus_desc">' + result.desc + '</div>');
                                          }
                                       });
                                    }
                                 });
                              },
                              setup: function( data ) {
                                 if( data.term_id ) {
                                    var me = this;
                                    Page.sendAction('get_term',{id:data.term_id, lang:'en'}, function( result ){
                                       if( result && result.name ) {
                                          me.setValue( result.name );
                                          me.getDialog().getContentElement('english','descriptionText').getInputElement().setHtml('<div class="ved_thesaurus_desc">' + result.desc + '</div>');
                                       }
                                    });
                                 }
                              },
                              commit: function( data ) {
                                 if( this.getDialog()._.currentTabId == 'english' )
                                    data.name = this.getValue();
                              }
                           },
                           {
                              id: 'engTermId',
                              type: 'text',
                              label: 'TermId',
                              hidden: true,
                              'default': '',
                              setup: function( data ) {
                                 if( data.term_id )
                                    this.setValue( data.term_id );
                              },
                              commit: function( data ) {
                                 if( this.getDialog()._.currentTabId == 'english' )
                                    data.term_id = this.getValue();
                              }
                           },
                           {
                              id: 'descriptionText',
                              type: 'html',
                              // style: 'display:block; padding-top: 5px; white-space: normal;',
                              html: '',
                              reset: function() {
                                 this.getInputElement().setHtml('');
                              }
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      ],
      onShow: function() {
         var editor = this.getParentEditor(),
            selection = editor.getSelection(),
            element = null;

         // this.reset();

         // Fill in all the relevant fields if there's already one link selected.
         if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) )
            selection.selectElement( element );
         else
            element = null;


         var data = parseLink.apply( this, [ editor, element ] );

         this.selectPage( data.lang && data.lang == 'en' ? 'english' : 'russian');
         this.setupContent(data);
      },
      onOk: function() {
         var attributes = {},
            removeAttributes = [],
            data = {},
            me = this,
            editor = this.getParentEditor();

         this.commitContent( data );

         if( this._.currentTabId == 'russian' ) {
            attributes[ 'data-ved-saved-href' ] = editor.config.thesaurusSourcePatternRu.replace('{term_id}', data.term_id);
         } else if( this._.currentTabId == 'english' ) {
            attributes[ 'data-ved-saved-href' ] = editor.config.thesaurusSourcePatternEn.replace('{term_id}', data.term_id);
         } else {
            return;
         }

         attributes.target = '_blank';
         attributes['class'] = editor.config.thesaurusTagClass;

         var selection = editor.getSelection();

         // Browser need the "href" fro copy/paste link to work. (#6641)
         attributes.href = attributes[ 'data-ved-saved-href' ];

         if ( !this._.selectedElement ) {
            var range = selection.getRanges( 1 )[ 0 ];

            // Use link URL as text with a collapsed cursor.
            if ( range.collapsed ) {
               // Short mailto link text view (#5736).
               var text = new VED.dom.text( data.name, editor.document );
               range.insertNode( text );
               range.selectNodeContents( text );
            }

            // Apply style.
            var style = new VED.style({ element: 'a', attributes: attributes } );
            style.type = VED.STYLE_INLINE; // need to override... dunno why.
            style.applyToRange( range );
            range.select();
         } else {
            // We're only editing an existing link, so just overwrite the attributes.
            var element = this._.selectedElement,
               href = element.data( 'ved-saved-href' ),
               textView = element.getHtml();

            element.setAttributes( attributes );
            element.removeAttributes( removeAttributes );

            selection.selectElement( element );
            delete this._.selectedElement;
         }

      },
      onCancel: function() {

      }
   };


   return dialogDefiniton;
});





